import { createRequire } from "node:module"

const require = createRequire(import.meta.url)
// @ts-ignore
const lib = require('../index.node')

/**
 * @param {string} name
 */
export function hello(name) {
    return lib.hello(name)
}

export const sleep = (/** @type {number} */ timeout) => new Promise((resolve) => setTimeout(resolve, timeout))

/**
 * @param {'left'|'right'|'middle'} button 
 */
export function mouseDown(button) {
    switch (button) {
        case 'left':
            return lib.mouseEvent(0x0002, 0, 0, 0) // MOUSEEVENTF_LEFTDOWN
        case 'right':
            return lib.mouseEvent(0x0008, 0, 0, 0) // MOUSEEVENTF_RIGHTDOWN
        case 'middle':
            return lib.mouseEvent(0x0020, 0, 0, 0) // MOUSEEVENTF_MIDDLEDOWN
        default:
            throw new Error('Invalid mouse button')
    }
}

/**
 * @param {'left'|'right'|'middle'} button 
 */
export function mouseUp(button) {
    switch (button) {
        case 'left':
            return lib.mouseEvent(0x0004, 0, 0, 0) // MOUSEEVENTF_LEFTUP
        case 'right':
            return lib.mouseEvent(0x0010, 0, 0, 0) // MOUSEEVENTF_RIGHTUP
        case 'middle':
            return lib.mouseEvent(0x0040, 0, 0, 0) // MOUSEEVENTF_MIDDLEUP
        default:
            throw new Error('Invalid mouse button')
    }
}

/**
 * @param {'left'|'right'|'middle'} button 
 */
export function mouseClick(button) {
    switch (button) {
        case 'left':
            lib.mouseEvent(0x0002, 0, 0, 0) // MOUSEEVENTF_LEFTDOWN
            return lib.mouseEvent(0x0004, 0, 0, 0) // MOUSEEVENTF_LEFTUP
        case 'right':
            lib.mouseEvent(0x0008, 0, 0, 0) // MOUSEEVENTF_RIGHTDOWN
            return lib.mouseEvent(0x0010, 0, 0, 0) // MOUSEEVENTF_RIGHTUP
        case 'middle':
            lib.mouseEvent(0x0020, 0, 0, 0) // MOUSEEVENTF_MIDDLEDOWN
            return lib.mouseEvent(0x0040, 0, 0, 0) // MOUSEEVENTF_MIDDLEUP
        default:
            throw new Error('Invalid mouse button')
    }
}

/**
 * @param {number} x 
 * @param {number} y 
 */
export function mouseMove(x, y) {
    // 直接使用相对移动，不需要转换坐标
    return lib.mouseEvent(0x0001, x, y, 0) // MOUSEEVENTF_MOVE
}

/**
 * @param {number} x 
 * @param {number} y 
 */
export function mouseMoveTo(x, y) {
    // 转换像素坐标到 0-65535 范围
    const screenWidth = lib.getSystemMetrics(0)  // SM_CXSCREEN
    const screenHeight = lib.getSystemMetrics(1) // SM_CYSCREEN

    const absoluteX = Math.round((x * 65535) / (screenWidth - 1))
    const absoluteY = Math.round((y * 65535) / (screenHeight - 1))

    return lib.mouseEvent(0x0001 | 0x8000, absoluteX, absoluteY, 0) // MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE
}

/**
 * 转换坐标以适配高DPI屏幕
 * @param {number} x 
 * @param {number} y 
 * @returns {{x: number, y: number}} 转换后的坐标
 */
function convertCoordsForHighDPI(x, y) {
    // 获取屏幕尺寸
    const screenWidth = lib.getSystemMetrics(0)  // SM_CXSCREEN
    const screenHeight = lib.getSystemMetrics(1) // SM_CYSCREEN

    // 尝试检测DPI缩放因子
    let dpiScaleX = 1.0
    let dpiScaleY = 1.0

    try {
        // 使用启发式方法检测DPI缩放
        // 获取工作区域尺寸，这可能与屏幕尺寸不同
        const desktopWidth = lib.getSystemMetrics(78)  // SM_CXVIRTUALSCREEN
        const desktopHeight = lib.getSystemMetrics(79) // SM_CYVIRTUALSCREEN

        // 如果虚拟屏幕和物理屏幕尺寸不同，可能存在缩放
        if (desktopWidth > 0 && screenWidth > 0) {
            dpiScaleX = desktopWidth / screenWidth
            dpiScaleY = desktopHeight / screenHeight
        }
    } catch (e) {
        // 出错时使用默认值
        dpiScaleX = 1.0
        dpiScaleY = 1.0
    }

    // 应用DPI缩放因子
    x = x * dpiScaleX
    y = y * dpiScaleY

    // 转换像素坐标到 0-65535 范围
    const absoluteX = Math.round((x * 65535) / (screenWidth - 1))
    const absoluteY = Math.round((y * 65535) / (screenHeight - 1))

    return { x: absoluteX, y: absoluteY }
}

/**
 * @param {'up'|'down'} direction 
 */
export function mouseWheel(direction) {
    switch (direction) {
        case 'up':
            return lib.mouseEvent(0x0800, 0, 0, 120) // MOUSEEVENTF_WHEEL
        case 'down':
            return lib.mouseEvent(0x0800, 0, 0, -120) // MOUSEEVENTF_WHEEL
        default:
            throw new Error('Invalid wheel direction')
    }
}

/**
 * @param {number} x 
 * @param {number} y 
 * @param {number} w 
 * @param {number} h 
 */
export function screenshot(x, y, w, h) {
    return lib.screenshot(x, y, w, h)
}

/**
 * 获取屏幕尺寸（物理像素）
 * @returns {{width: number, height: number}} 屏幕尺寸对象
 */
export function getScreenSize() {

    for (let i = 0; i < 5000; i++) {
        if(lib.getSystemMetrics(i)>1000){
            console.info('========',i, lib.getSystemMetrics(i))
        }
        
    }

    const screenWidth = lib.getSystemMetrics(0)  // SM_CXSCREEN
    const screenHeight = lib.getSystemMetrics(1) // SM_CYSCREEN
    return { width: screenWidth, height: screenHeight }
}

/**
 * @param {number} keycode 
 * @param {number} flags 
 */
export function keybdEvent(keycode, flags) {
    return lib.keybdEvent(keycode, flags)
}

/**
 * @param {number} flags 
 * @param {number} dx 
 * @param {number} dy 
 * @param {number} data 
 */
export function mouseEvent(flags, dx, dy, data) {
    return lib.mouseEvent(flags, dx, dy, data)
}

/**
 * @param {string} key 
 */
export function keyDown(key) {
    // 实现键码映射逻辑，然后调用keybdEvent
    const vk = mapKeyToVk(key)
    if (vk !== undefined) {
        return lib.keybdEvent(vk, 0) // 0表示按下
    }
    throw new Error(`Unknown key: ${key}`)
}

/**
 * @param {string} key 
 */
export function keyUp(key) {
    // 实现键码映射逻辑，然后调用keybdEvent
    const vk = mapKeyToVk(key)
    if (vk !== undefined) {
        return lib.keybdEvent(vk, 2) // 2表示KEYEVENTF_KEYUP
    }
    throw new Error(`Unknown key: ${key}`)
}

/**
 * 将键名映射到虚拟键码
 * @param {string} key 
 * @returns {number|undefined}
 */
function mapKeyToVk(key) {
    // 字母键
    if (key.length === 1 && /[A-Z]/.test(key)) {
        return key.charCodeAt(0)
    }

    // 数字键
    if (key.length === 1 && /[0-9]/.test(key)) {
        return key.charCodeAt(0)
    }

    // 特殊键映射
    const specialKeys = {
        '{ENTER}': 0x0D,
        '{SPACE}': 0x20,
        '{BACKSPACE}': 0x08,
        '{TAB}': 0x09,
        '{ESC}': 0x1B,
        '{SHIFT}': 0x10,
        '{CTRL}': 0x11,
        '{ALT}': 0x12,
        '{WIN}': 0x5B,
        '{CAPSLOCK}': 0x14,
        '{NUMLOCK}': 0x90,
        '{SCROLLLOCK}': 0x91,
        '{F1}': 0x70,
        '{F2}': 0x71,
        '{F3}': 0x72,
        '{F4}': 0x73,
        '{F5}': 0x74,
        '{F6}': 0x75,
        '{F7}': 0x76,
        '{F8}': 0x77,
        '{F9}': 0x78,
        '{F10}': 0x79,
        '{F11}': 0x7A,
        '{F12}': 0x7B,
        '{LEFT}': 0x25,
        '{UP}': 0x26,
        '{RIGHT}': 0x27,
        '{DOWN}': 0x28,
        ';': 0xBA,
        '=': 0xBB,
        ',': 0xBC,
        '-': 0xBD,
        '.': 0xBE,
        '/': 0xBF,
        '`': 0xC0,
        '[': 0xDB,
        '\\': 0xDC,
        ']': 0xDD,
        "'": 0xDE
    }

    return specialKeys[key]
}

/**
 * 获取系统DPI缩放因子
 * @returns {number} DPI缩放因子
 */
function getDpiScale() {
    try {
        // 尝试获取更准确的DPI信息
        // SM_CXSCREEN = 0, SM_CYSCREEN = 1
        // SM_CXVIRTUALSCREEN = 78, SM_CYVIRTUALSCREEN = 79
        const virtualScreenWidth = lib.getSystemMetrics(78)  // SM_CXVIRTUALSCREEN
        const screenWidth = lib.getSystemMetrics(0)          // SM_CXSCREEN

        // 如果虚拟屏幕尺寸和实际屏幕尺寸不同，说明有DPI缩放
        if (screenWidth > 0 && virtualScreenWidth > 0 && virtualScreenWidth !== screenWidth) {
            return virtualScreenWidth / screenWidth
        }
    } catch (e) {
        // 忽略错误，使用默认值
    }

    // 默认返回1，表示无缩放
    return 1.0
}

/**
 * @param {string[]} keys 
 */
export function sendkeys(keys) {
    return lib.sendkeys(keys)
}